#!/bin/bash
#Ubuntu18.04 update openssl&openssh
#请使用bash执行脚本: bash update-openssl-openssh.bash
#2022-06-15


trap "trap - TERM && kill -- -$$" INT TERM EXIT &>/dev/null
DIR=$(pwd)
Date_start=$(date +%s)
openssl_version=1.1.1o
openssh_version=9.0p1

Progress_bar() {
	i=0
	arr=('*' '|' '/' '-' '\\')
	index=0
	while [ $i -le 2000 ]; do
		index=$(echo $i%5)
		printf "[%c]\r" "${arr[$index]}"
		((i++))
		sleep 0.1
	done
}

Check() {
	#Check user.
	who=`whoami`
	group=`groups $who`
	if [[ $who =~ "root" ]];then
		echo
	else
		echo -e "\n\033[41;30m User:$who does not have root permission. \033[0m"
		exit 1
	fi

	#Check for OpenSSL&OpenSSH version.
	ssh -V
	echo -e "\n\033[32m Press Enter or wait for 3s to automatically start the update. \033[0m"
	read -t 3 -p "------------------------------------------------------------"

	Prepare
}

Prepare() {
	#Download the source packages.
	echo -ne "\n\033[32m    [1/8]Download the source packages... \033[0m"
	Progress_bar &	
	wget --no-check-certificate https://www.openssl.org/source/openssl-$openssl_version.tar.gz &>/dev/null && \
	wget --no-check-certificate https://mirrors.aliyun.com/pub/OpenBSD/OpenSSH/portable/openssh-$openssh_version.tar.gz &>/dev/null
	if [ $? != 0 ]; then
		kill $!
		wait $! &>/dev/null
		echo -e "\n\033[41;30m Download failed. \033[0m"
		exit 1
	fi	
	tar -zxf openssl-$openssl_version.tar.gz
	tar -zxf openssh-$openssh_version.tar.gz
	kill $!
	wait $! &>/dev/null

	Install_dependent
}

Install_dependent() {
	#Install dependent packages.
	echo -ne "\n\033[32m    [2/8]Installing dependent packages... \033[0m"
	Progress_bar &
	apt-get install -y make gcc zlib1g-dev libpam0g-dev &>$DIR/dependent_install.log
	kill $!
	wait $! &>/dev/null

	Update_openssl
}

Update_openssl() {
	#Remove the old version of OpenSSL.
	apt-get remove -y openssl &>/dev/null
	
	#Make install OpenSSL.
	cd $DIR/openssl-$openssl_version/
	echo -ne "\n\033[32m    [3/8]Config OpenSSL... \033[0m"
	Progress_bar &
	./config &>$DIR/openssl_config.log
	if [ $? != 0 ]; then
		kill $!
		wait $! &>/dev/null
		echo -e "\n\033[41;30m Config OpenSSL failed.Please check the log files for error messages:openssl_config.log \033[0m"
		exit 1
	else
		kill $!
		wait $! &>/dev/null
		echo -ne "\n\033[32m    [4/8]Make install OpenSSL... \033[0m"
		Progress_bar &
	fi
	make clean &>/dev/null
	make -j8 &>$DIR/openssl_install.log
	make install &>>$DIR/openssl_install.log
	if [ $? != 0 ]; then
		kill $!
		wait $! &>/dev/null
		echo -e "\n\033[41;30m Make insatall OpenSSL failed.Please check the log files for error messages:openssl_install.log \033[0m"
		exit 1
	else
		kill $!
		wait $! &>/dev/null
		echo -ne "\n\033[32m    [5/8]Configuring OpenSSL... \033[0m"
		Progress_bar &
		sleep 1
	fi

	#Configure OpenSSL.
	ldconfig &>/dev/null

	#Check for OpenSSL version.
	openssl version | grep $openssl_version &>/dev/null
	if [ $? != 0 ]; then
		kill $!
		wait $! &>/dev/null
		echo -e "\n\033[41;30m Failed to update OpenSSL. \033[0m"
		exit 1
	fi
	kill $!
	wait $! &>/dev/null

	Update_openssh
}

Update_openssh() {
	#Remove & backup the old version of OpenSSH.
	mv /etc/ssh /etc/ssh.bak$(date +%Y%m%d) &>/dev/null
	mv /etc/init.d/ssh /etc/init.d/ssh.bak$(date +%Y%m%d) &>/dev/null
	mv /lib/systemd/system/ssh.service /lib/systemd/system/ssh.service.bak$(date +%Y%m%d) &>/dev/null
	apt-get remove -y openssh-server openssh-client &>/dev/null

	#Make install OpenSSH.
	cd $DIR/openssh-$openssh_version/
	echo -ne "\n\033[32m    [6/8]Config OpenSSH... \033[0m"
	Progress_bar &
	./configure \
		--prefix=/usr \
		--sysconfdir=/etc/ssh \
		--with-openssl-includes=/usr/local/include/openssl \
		--with-ssl-dir=/usr/local \
		--with-zlib \
		--with-md5-passwords \
		--with-pam &>$DIR/openssh_config.log
	if [ $? != 0 ]; then
		kill $!
		wait $! &>/dev/null
		echo -e "\n\033[41;30m Config OpenSSH failed.Please check the log files for error messages:openssh_config.log \033[0m"
		exit 1
	else
		kill $!
		wait $! &>/dev/null
		echo -ne "\n\033[32m    [7/8]Make install OpenSSH... \033[0m"
		Progress_bar &
	fi
	make clean &>/dev/null
	make -j8 &>$DIR/openssh_install.log
	make install &>>$DIR/openssh_install.log
	if [ $? != 0 ]; then
		kill $!
		wait $! &>/dev/null
		echo -e "\n\033[41;30m Make insatall OpenSSH failed.Please check the log files for error messages:openssh_install.log \033[0m"
		exit 1
	else
		kill $!
		wait $! &>/dev/null
		echo -ne "\n\033[32m    [8/8]Configuring OpenSSH... \033[0m"
		Progress_bar &
	fi

	#Configure OpenSSH.
	sed -i 's/#PermitRootLogin prohibit-password/PermitRootLogin yes/g' /etc/ssh/sshd_config
	sed -i 's/#UseDNS no/UseDNS no/g' /etc/ssh/sshd_config
	sed -i 's/#PasswordAuthentication yes/PasswordAuthentication yes/g' /etc/ssh/sshd_config
	sed -i 's/#UsePAM no/UsePAM yes/g' /etc/ssh/sshd_config	
	systemctl unmask ssh.service &>/dev/null
	mv /etc/init.d/ssh.bak$(date +%Y%m%d) /etc/init.d/ssh &>/dev/null
	systemctl daemon-reload &>/dev/null
	systemctl restart sshd &>/dev/null

	sleep 2
	kill $!
	wait $! &>/dev/null

	End
}

End() {

	#Check for OpenSSL&OpenSSH version.
	Current_version=$(ssh -V 2>&1)
	Successful_version="OpenSSH_$openssh_version, OpenSSL $openssl_version"

	if [[ "$Current_version" != *"$Successful_version"* ]]; then
		echo -e "\n\n\033[41;30m Failed to update OpenSSH. \033[0m"
		exit 1
	fi

	#Delete and restore files.
	cd $DIR
	rm -rf openssl*
	rm -rf openssh*
	rm -rf *.log

	#Print information.
	Date_end=$(date +%s)
	Difference=$((Date_end - Date_start))
	echo -e "\n------------------------------------------------------------\n"
	echo -e "\033[42;30m OpenSSL&OpenSSH update succeeded. \033[0m"
	echo Current_version:$Current_version
	echo Use_time:$Difference seconds.
	echo -e "\n------------------------------------------------------------"
	exit
}

Check
Prepare
Install_dependent
Update_openssl
Update_openssh
End
